package net.pws.common.beanutils;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;

import net.pws.common.beanutils.converter.DateConverter;

import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.converters.BigIntegerConverter;
import org.apache.commons.beanutils.converters.BooleanConverter;
import org.apache.commons.beanutils.converters.ByteConverter;
import org.apache.commons.beanutils.converters.CharacterConverter;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.beanutils.converters.ShortConverter;


@SuppressWarnings("rawtypes")
public class ConvertUtils extends org.apache.commons.beanutils.ConvertUtils {
    
    static {
        initRegister();
    }
    
    public static void initRegister() {
        register(new BigDecimalConverter(null), BigDecimal.class);
        register(new BigIntegerConverter(null), BigInteger.class);
        register(new BooleanConverter(null), Boolean.class);
        register(new ByteConverter(null), Byte.class);
        register(new CharacterConverter(null), Character.class);
        register(new DoubleConverter(null), Double.class);
        register(new FloatConverter(null), Float.class);
        register(new IntegerConverter(null), Integer.class);
        register(new LongConverter(null), Long.class);
        register(new ShortConverter(null), Short.class);
        register(new DateConverter(new String[] { "yyyy-MM-dd",
                                                 "yyyy-MM-dd HH:mm:ss",
                                                 "HH:mm:ss" }), Date.class);
    }
    
    // convert Object to specified type
    /**
     * @param value
     * @param clazz
     * @return
     */
    public static Object convertObject2SpecifiedType(Object value, Class clazz) {
        Converter converter = lookup(clazz);
        if (converter == null) {
            throw new IllegalArgumentException("No converter found for " + clazz);
        }
        return converter.convert(clazz, value);
    }
    
    public static String convertObject2String(Object value) {
        return (String) convertObject2SpecifiedType(value, String.class);
    }
    
    public static Boolean convertObject2Boolean(Object value) {
        return (Boolean) convertObject2SpecifiedType(value, Boolean.class);
    }
    
    public static Integer convertObject2Integer(Object value) {
        return (Integer) convertObject2SpecifiedType(value, Integer.class);
    }
    
    public static Long convertObject2Long(Object value) {
        return (Long) convertObject2SpecifiedType(value, Long.class);
    }
    
    public static Short convertObject2Short(Object value) {
        return (Short) convertObject2SpecifiedType(value, Short.class);
    }
    
    public static Byte convertObject2Byte(Object value) {
        return (Byte) convertObject2SpecifiedType(value, Byte.class);
    }
    
    public static Double convertObject2Double(Object value) {
        return (Double) convertObject2SpecifiedType(value, Double.class);
    }
    
    public static Float convertObject2Float(Object value) {
        return (Float) convertObject2SpecifiedType(value, Float.class);
    }
    
    public static Character convertObject2Character(Object value) {
        return (Character) convertObject2SpecifiedType(value, Character.class);
    }
    
    public static BigDecimal convertObject2BigDecimal(Object value) {
        return (BigDecimal) convertObject2SpecifiedType(value, BigDecimal.class);
    }
    
    public static BigInteger convertObject2BigInteger(Object value) {
        return (BigInteger) convertObject2SpecifiedType(value, BigInteger.class);
    }
    
    public static Date convertObject2Date(Object value) {
        return (Date) convertObject2SpecifiedType(value, Date.class);
    }
    
    public static java.sql.Date convertObject2SqlDate(Object value) {
        return (java.sql.Date) convertObject2SpecifiedType(value,
                                                           java.sql.Date.class);
    }
    
    public static Time convertObject2SqlTime(Object value) {
        return (Time) convertObject2SpecifiedType(value, java.sql.Time.class);
    }
    
    public static Timestamp convertObject2SqlTimestamp(Object value) {
        return (Timestamp) convertObject2SpecifiedType(value,
                                                       java.sql.Timestamp.class);
    }
    
	public static Class convertObject2Class(Object value) {
        return (Class) convertObject2SpecifiedType(value, Class.class);
    }
    
    public static File convertObject2File(Object value) {
        return (File) convertObject2SpecifiedType(value, File.class);
    }
    
    // convert String to specified type
    /**
     * @param value
     * @param clazz
     * @return
     * @see org.apache.commons.beanutils.ConvertUtils#convert(String, Class)
     */
    public static Object convertString2SpecifiedType(String value, Class clazz) {
        Converter converter = lookup(clazz);
        if (converter == null) {
            throw new IllegalArgumentException("No converter found for " + clazz);
        }
        return converter.convert(clazz, value);
    }
    
    public static String convertString2String(String value) {
        return (String) convertString2SpecifiedType(value, String.class);
    }
    
    public static Boolean convertString2Boolean(String value) {
        return (Boolean) convertString2SpecifiedType(value, Boolean.class);
    }
    
    public static Integer convertString2Integer(String value) {
        return (Integer) convertString2SpecifiedType(value, Integer.class);
    }
    
    public static Long convertString2Long(String value) {
        return (Long) convertString2SpecifiedType(value, Long.class);
    }
    
    public static Short convertString2Short(String value) {
        return (Short) convertString2SpecifiedType(value, Short.class);
    }
    
    public static Byte convertString2Byte(String value) {
        return (Byte) convertString2SpecifiedType(value, Byte.class);
    }
    
    public static Double convertString2Double(String value) {
        return (Double) convertString2SpecifiedType(value, Double.class);
    }
    
    public static Float convertString2Float(String value) {
        return (Float) convertString2SpecifiedType(value, Float.class);
    }
    
    public static Character convertString2Character(String value) {
        return (Character) convertString2SpecifiedType(value, Character.class);
    }
    
    public static BigDecimal convertString2BigDecimal(String value) {
        return (BigDecimal) convertString2SpecifiedType(value, BigDecimal.class);
    }
    
    public static BigInteger convertString2BigInteger(String value) {
        return (BigInteger) convertString2SpecifiedType(value, BigInteger.class);
    }
    
    public static Date convertString2Date(String value) {
        return (Date) convertString2SpecifiedType(value, Date.class);
    }
    
    public static java.sql.Date convertString2SqlDate(String value) {
        return (java.sql.Date) convertString2SpecifiedType(value,
                                                           java.sql.Date.class);
    }
    
    public static Time convertString2SqlTime(String value) {
        return (Time) convertString2SpecifiedType(value, java.sql.Time.class);
    }
    
    public static Timestamp convertString2SqlTimestamp(String value) {
        return (Timestamp) convertString2SpecifiedType(value,
                                                       java.sql.Timestamp.class);
    }
    
    public static Class convertString2Class(String value) {
        return (Class) convertString2SpecifiedType(value, Class.class);
    }
    
    public static File convertString2File(String value) {
        return (File) convertString2SpecifiedType(value, File.class);
    }
    
}
